/*!
 Temelia - Skip-list samples.

 Copyright (C) 2008 Ceata (http://ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "include/samples.h"
#include <temelia/skip_list.h>

static void sample1()
{
	int *x;
	int N, i;
	skip_list_t list;

	PRINT("\n\n Sample 1 started \n\n");

	N = 100;
	list = skip_list_new(16);

	for (i = 0; i < N; i++)
	{
		x = int_new(rand() % 1000);
		if (!skip_list_insert(list, x, int_compare, NULL))
			int_delete(x, NULL);
	}

	skip_list_iterate(list, int_handler, NULL);
	skip_list_iterate_level(list, 0, int_delete, NULL);
	skip_list_delete(list);

	PRINT("\n\n Sample 1 ended \n\n");
}

static void sample2()
{
	/*
	 * You don't have to store as duplicated the pointers on the heap;
	 * see the above example for iterating the skip-list and deleting the
	 * allocated user-space memory.
	 * In this example I use int **x, because I want to use skip_list_remove for some keys.
	 */
	int **x, N, i;
	skip_list_t list;

	PRINT("\n\n Sample 1 started \n\n");

	N = 100;
	list = skip_list_new(16);
	x = int_array_new(N, 1000);

	for (i = 0; i < N; i++)
		skip_list_insert(list, x[i], int_compare, NULL);

	PRINT("Initial list\n");
	for (i = 15; i >= 0; i--)
	{
		PRINT("Level %d : ", i);
		skip_list_iterate_level(list, i, int_handler, NULL);
		PRINT("\n\n");
	}

	for (i = 0; i < N; i++)
		if (skip_list_search(list, x[i], int_compare, NULL) == NULL)
			PRINT("Report this error on line %d\n", __LINE__);

	for (i = 0; i < N / 2; i++)
		skip_list_remove(list, x[i], int_compare, NULL);

	PRINT("After some keys removing\n");
	for (i = 15; i >= 0; i--)
	{
		PRINT("Level %d : ", i);
		skip_list_iterate_level(list, i, int_handler, NULL);
		PRINT("\n\n");
	}

	skip_list_delete(list);
	int_array_delete(x, N);

	PRINT("\n\n Sample 1 ended \n\n");
}

static void sample3()
{
	skip_list_t skip_list_node;
	int i;

	skip_list_node = skip_list_new(10);

	skip_list_node_set_key(skip_list_node, (void *) 0x123456);
	PRINT("key = %p\n", skip_list_node_get_key(skip_list_node));

	PRINT("level = %d\n", skip_list_node_get_level(skip_list_node));

	PRINT("next list = %p\n", skip_list_node_get_next(skip_list_node));

	for (i = -10; i <= 10; i++)
		PRINT("level = %d, next = %p\n", i, skip_list_node_get_next_level(skip_list_node, i));

	skip_list_node_delete(skip_list_node);
}

void run_skip_list_samples()
{
	sample1();
	sample2();
	sample3();
}
